package code.cando;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Stack;

/**
 * author : yeswater
 * date : 2023/12/6
 * <p>
 * <p>
 * 有效的括号
 * 1 左括号必须用相同类型的右括号闭合
 * 2 左括号必须以正确的顺序闭合 )( , ()
 * 3 每个括号都有一个对象的相同类型的左括号
 * <p>
 * 0323-0420
 */

public class T020 {
    public static void main(String[] args) {
        String s = "]";
        System.out.println(isValid(s));
    }

    // 理解错题意 : 以为只要这样就算通过 ([)] ,这样实际上不行
    public static boolean isValid1(String s) {
        int length = s.length();
        char[] chars = s.toCharArray();
        HashMap<String, Integer> map = new HashMap<>();
        map.put("s", 0); // ()
        map.put("m", 0); // []
        map.put("l", 0); // {}
        for (int i = 0; i < length; i++) {
            Integer ss = map.get("s");
            Integer mm = map.get("m");
            Integer ll = map.get("l");

            if (chars[i] == '(') {
                map.put("s", ss + 1);
            }
            if (chars[i] == ')') {
                if (ss < 1) {
                    return false;
                }
                map.put("s", ss - 1);
            }

            //
            if (chars[i] == '[') {
                map.put("m", mm + 1);
            }
            if (chars[i] == ']') {
                if (mm < 1) {
                    return false;
                }
                map.put("m", mm - 1);
            }

            //
            if (chars[i] == '{') {
                map.put("l", ll + 1);
            }
            if (chars[i] == '}') {
                if (ll < 1) {
                    return false;
                }
                map.put("l", ll - 1);
            }
        }
        return map.get("s") == 0 && map.get("m") == 0 && map.get("l") == 0;
    }

    /**
     * 常用方法
     * stack.pop();
     * stack.peek();
     * stack.push();
     * stack.empty();
     */
    public static boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();

        HashMap<Character, Character> map = new HashMap() {
        };
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');
        HashSet<Character> setR = new HashSet<>();
        setR.add(')');
        setR.add('}');
        setR.add(']');
        HashSet<Character> setL = new HashSet<>();
        setL.add('(');
        setL.add('{');
        setL.add('[');
        char[] chars = s.toCharArray();
        for (char aChar : chars) {
            if (setL.contains(aChar)) {
                stack.push(aChar);
            } else if (setR.contains(aChar)) { // 是反括号
                // 遇到正括号消除
                if (stack.size() == 0) return false;
                if (map.get(aChar) == stack.peek()) {
                    stack.pop();
                } else {
                    stack.push(aChar);
                }
            }
        }
        return stack.size() == 0;
    }
}
